package cn.iocoder.yudao.module.trade.service.drainage;

import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.trade.controller.admin.orderpostback.vo.OrderPostBackSaveReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.orderpostback.OrderPostBackDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.orderpostconfig.OrderPostConfigDO;
import cn.iocoder.yudao.module.trade.enums.orderpostback.OrderPostBackPayTypeEnum;
import cn.iocoder.yudao.module.trade.enums.orderpostback.TradeOrderPostBackStatusEnum;
import cn.iocoder.yudao.module.trade.service.orderpostback.OrderPostBackService;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 变现猫
 */
@Slf4j
@Service
public class BxmDrainageServiceImpl implements DrainageService {

    @Getter
    @Setter
    public Integer drainageType = 1; //变现猫id
    @Value("${drainage.type.bxm.server:https://openlog.bianxianmao.com/inads/s.gif?mt=8&bxmid=%s&conversion_type=%d&pay_amount=%s}")
    private String serverUrl;

    @Resource
    private OrderPostBackService orderPostBackService;
    @Resource
    protected RestTemplate restTemplate;

    @Override
    public boolean processOrder(TradeOrderDO orderDO, Map<String, String> param, OrderPostConfigDO configDo, boolean send) {
        OrderPostBackSaveReqVO saveReqVO = createOrderPostBack(orderDO, param.get("bxm_id"), drainageType,
                orderDO.getPayPrice(), 1, configDo, send ? TradeOrderPostBackStatusEnum.UN_SEND : TradeOrderPostBackStatusEnum.OFF_SHELF);
        if (send) {
            sendOrder(saveReqVO);
        }
        orderPostBackService.createOrderPostBack(saveReqVO);
        return true;
    }

    @Override
    public boolean processOrder(OrderPostBackDO orderPostBackDO) {
        OrderPostBackSaveReqVO saveReqVO = BeanUtils.toBean(orderPostBackDO, OrderPostBackSaveReqVO.class);
        sendOrder(saveReqVO, true);
        orderPostBackService.createOrderPostBack(saveReqVO);
        return true;
    }

    private boolean sendOrder(OrderPostBackSaveReqVO saveReqVO, boolean retry) {
        int type;
        if (OrderPostBackPayTypeEnum.PAY.getType().equals(saveReqVO.getOrderType())) {
            type = 5;
        } else if (OrderPostBackPayTypeEnum.REFUND.getType().equals(saveReqVO.getOrderType())) {
            type = 8;
        } else {
            log.error("未找到对应回传类型: {}", saveReqVO.getOrderType());
            return false;
        }
        try {
            BigDecimal postPrice = BigDecimal.valueOf(saveReqVO.getPostPrice())
                    .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
            ResponseEntity<String> response = restTemplate.getForEntity(
                    String.format(serverUrl, saveReqVO.getThirdId(), type, postPrice.toString()),
                    String.class
            );
            boolean success = response.getStatusCode().is2xxSuccessful();
            saveReqVO.setStatus(success ?
                    TradeOrderPostBackStatusEnum.FINISH.getStatus() :
                    retry ? TradeOrderPostBackStatusEnum.FAILED.getStatus() : TradeOrderPostBackStatusEnum.RETRY_FAILED.getStatus());
            return success;
        } catch (Exception e) {
            log.error("回传变现猫数据失败：{}", e.getMessage());
            saveReqVO.setStatus(retry ? TradeOrderPostBackStatusEnum.FAILED.getStatus() : TradeOrderPostBackStatusEnum.RETRY_FAILED.getStatus());
            return false;
        } finally {
            saveReqVO.setPostTime(LocalDateTime.now());
        }
    }

    @Override
    public boolean unPayOrderPost(TradeOrderDO tradeOrderDO, Map<String, String> param, OrderPostConfigDO configDO) {
        return false;
    }

    private boolean sendOrder(OrderPostBackSaveReqVO saveReqVO) {
        return sendOrder(saveReqVO, false);
    }
}
